package com.hoshiicloud.user.service.impl.rbac;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hoshiicloud.auth.vo.TokenUsersVO;
import com.hoshiicloud.common.aop.Logable;
import com.hoshiicloud.common.exception.CommonError;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.rbac.entity.SysPermissiones;
import com.hoshiicloud.rbac.entity.SysRoles;
import com.hoshiicloud.user.entity.company.Member;
import com.hoshiicloud.user.entity.platform.PlatUsers;
import com.hoshiicloud.user.entity.platform.Platform;
import com.hoshiicloud.user.entity.store.PlatStore;
import com.hoshiicloud.user.entity.store.StoreDepartment;
import com.hoshiicloud.user.entity.store.StoreUsers;
import com.hoshiicloud.user.feign.IdGeneratorService;
import com.hoshiicloud.user.mapper.rbac.IMemberMapper;
import com.hoshiicloud.user.service.platform.PlatUsersService;
import com.hoshiicloud.user.service.platform.PlatformService;
import com.hoshiicloud.user.service.rbac.IMemberService;
import com.hoshiicloud.user.service.rbac.ISysPermissionesService;
import com.hoshiicloud.user.service.rbac.ISysRolesService;
import com.hoshiicloud.user.service.store.PlatStoreService;
import com.hoshiicloud.user.service.store.StoreDepartmentService;
import com.hoshiicloud.user.service.store.StoreUsersService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 租户会员Service接口实现类
 *
 * @author : yangcheng
 * @date : 2019/5/15 15:23
 * @mail : maiboyc@163.com
 **/
@Service
@Slf4j
public class MemberServiceImpl extends ServiceImpl<IMemberMapper, Member> implements IMemberService {

    // id生成Service
    @Autowired
    private IdGeneratorService idGeneratorService;

    // 租户会员Mapper
    @Autowired
    private IMemberMapper memberMapper;

    @Autowired
    private ISysRolesService sysRolesService;
    @Autowired
    private ISysPermissionesService sysPermissionesService;
    @Autowired
    private StoreUsersService storeUsersService;

    @Autowired
    private StoreDepartmentService storeDepartmentService;
    @Autowired
    private PlatStoreService platStoreService;
    @Autowired
    private PlatformService platformService;

    @Autowired
    private PlatUsersService platUsersService;
    /**
     * 根据id获取
     *
     * @param id ID
     * @return Member
     */
    @Cacheable(cacheNames = "member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#id")
    @Logable(authName = "租户管理-租户会员管理-根据ID查询租户会员信息")
    @Override
    public Member getById(Long id) {
        return baseMapper.selectById(id);
    }

    /**
     * 根据一组id
     *
     * @param ids id组
     * @return List<Member>
     */
    @Cacheable(cacheNames = "member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#ids")
    @Logable(authName = "租户管理-租户会员管理-根据ID组查询租户会员信息")
    @Override
    public List<Member> getByIds(List<Long> ids) {
        return baseMapper.selectBatchIds(ids);
    }

    /**
     * 保存
     *
     * @param entity 实体对象
     * @return Long
     */
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "member", allEntries = true)
    @Logable(authName = "租户管理-租户会员管理-新增租户会员信息")
    @Override
    public Long insert(Member entity) throws ServiceException {
        int row = baseMapper.insert(entity);
        if (row <= 0) {
            throw new ServiceException(CommonError.error("新增租户会员信息失败"));
        }
        return entity.getId();
    }

    /**
     * 修改
     *
     * @param entity 实体对象
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "member", allEntries = true)
    @Logable(authName = "租户管理-租户会员管理-修改租户会员信息")
    @Override
    public Long update(Member entity) throws ServiceException {
        int row = 0;
        try {
            row = baseMapper.updateById(entity);
        } catch (ServiceException e) {
            e.getError();
        } catch (Exception e) {
            e.getMessage();
        }

        if (row <= 0) {
            throw new ServiceException(CommonError.error("修改租户会员信息失败"));
        }
        return entity.getId();
    }


    /**
     * 根据条件查询租户会员信息
     *
     * @param entity 查询参数
     * @return List<Member>
     */
    @Cacheable(cacheNames = "member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#entity.nickName+':'+#entity.toString()")
    @Logable(authName = "租户管理-租户会员管理-根据条件查询租户会员信息")
    @Override
    public List<Member> getMembers(Member entity) {
        List<Member> memberList = new ArrayList<>();
        try {
            QueryWrapper<Member> queryWrapper = buildQueryWrapper(entity);
            memberList = baseMapper.selectList(queryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return memberList;
    }

    /**
     * 根据微信用户唯一openid获取租户会员
     *
     * @param wxOpenId 微信用户唯一id
     * @return Member
     */
    @Cacheable(cacheNames = "member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#wxOpenId")
    @Logable(authName = "租户管理-租户会员管理-根据wxOpenId查询租户会员信息")
    @Override
    public Member getMemberByWxOpenId(String wxOpenId) {
        QueryWrapper<Member> queryWrapper = new QueryWrapper();
        List<Member> list = new ArrayList<Member>();
        // openId
        if (StringUtils.isNotEmpty(wxOpenId)) {
            queryWrapper.eq("wx_open_id", wxOpenId);
        }
        try {
            list = baseMapper.selectList(queryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 根据手机号码获取租户会员
     *
     * @param mobile 手机号码
     * @return Member
     */
    @Cacheable(cacheNames = "member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#companyId+':'+#mobile")
    @Logable(authName = "租户管理-租户会员管理-根据手机号码查询租户会员信息")
    @Override
    public Member getMemberByMobile(Long companyId,String mobile) {
        QueryWrapper<Member> queryWrapper = new QueryWrapper<Member>();
        List<Member> list = new ArrayList<Member>();
        // 手机号码
        queryWrapper.lambda().eq(companyId!=null,Member::getCompanyId,companyId).eq(StringUtils.isNotBlank(mobile),Member::getPhone,mobile);
        try {
            list = baseMapper.selectList(queryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 根据openId和手机号码获取租户会员信息
     *
     * @param wxOpenId 微信openId
     * @param mobile   手机号码
     * @return Member
     */
    @Cacheable(cacheNames = "member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#wxOpenId+':'+#mobile")
    @Logable(authName = "租户管理-租户会员管理-根据手机号码查询租户会员信息")
    @Override
    public Member getMemberByWxOpenIdOrMobile(String wxOpenId, String mobile) {
        QueryWrapper<Member> queryWrapper = new QueryWrapper();
        List<Member> list = new ArrayList<Member>();
        // openId和手机号码
        if (StringUtils.isNotEmpty(wxOpenId)) {
            queryWrapper.eq(StringUtils.isNotEmpty(wxOpenId), "wx_open_id", wxOpenId).or().eq(StringUtils.isNotEmpty(mobile), "phone", mobile);
        }
        try {
            list = baseMapper.selectList(queryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 删除
     *
     * @param id ID
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "member", allEntries = true)
    @Logable(authName = "租户管理-租户会员管理-删除租户会员信息")
    @Override
    public boolean delete(Long id) throws ServiceException {
        Member entity = this.getById(id);
        entity.setDeleted(1);
        int row = baseMapper.updateById(entity);
        if (row <= 0) {
            throw new ServiceException(CommonError.error("删除租户会员信息失败"));
        } else {
            return true;
        }
    }

    /**
     * 查询租户会员信息和平台会员信息
     * 租户会员信息来自members，平台会员信息来自plat_consumer,以member_id关联
     *
     * @param map 查询条件
     * @return Map<String, Object>
     */
    @Cacheable(cacheNames = "member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#key")
    @Logable(authName = "租户管理-租户会员管理-查询租户会员信息和平台会员信息")
    @Override
    public Map<String, Object> getMemberWithConsumerInfo(Map<String, Object> map, String key) {
        return memberMapper.getMemberWithConsumerInfo(map);
    }

    /**
     * 组装查询参数为QueryWrapper
     *
     * @param entity 查询参数实体
     * @return QueryWrapper<Member>
     */
    private QueryWrapper<Member> buildQueryWrapper(Member entity) {
        QueryWrapper<Member> queryWrapper = new QueryWrapper();
        // 用户编号
        if (StringUtils.isNotEmpty(entity.getUserCode())) {
            queryWrapper.like("user_code", entity.getUserCode());
        }
        // 昵称
        if (StringUtils.isNotEmpty(entity.getNickName())) {
            queryWrapper.like("nick_name", entity.getNickName());
        }
        // 姓名
        if (StringUtils.isNotEmpty(entity.getRealName())) {
            queryWrapper.like("real_name", entity.getRealName());
        }
        // 身份证
        if (StringUtils.isNotEmpty(entity.getIdCard())) {
            queryWrapper.like("id_card", entity.getIdCard());
        }
        // 地址
        if (StringUtils.isNotEmpty(entity.getAddress())) {
            queryWrapper.like("address", entity.getAddress());
        }
        // 手机号码
        if (StringUtils.isNotEmpty(entity.getPhone())) {
            queryWrapper.like("phone", entity.getPhone());
        }
        // 性别
        if (entity.getSex() != null) {
            queryWrapper.eq("sex", entity.getSex());
        }
        // 邮箱地址
        if (StringUtils.isNotEmpty(entity.getEmail())) {
            queryWrapper.like("email", entity.getEmail());
        }
        queryWrapper.lambda().eq(entity.getCompanyId()!=null,Member::getCompanyId,entity.getCompanyId())
        .eq(StringUtils.isNotBlank(entity.getPassword()),Member::getPassword,entity.getPassword())
        .eq(entity.getId()!=null,Member::getId,entity.getId());
        // 默认查询只查询未逻辑删除的数据
        queryWrapper.eq("deleted", 0);
        return queryWrapper;
    }

    /**
     * 根据租户姓名查询租户会员信息
     *
     * @param name
     * @return List<Member>
     */
    @Override
    public List<Member> memberList(String name) {
        List<Member> memberList;
        QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        memberList = list(queryWrapper);
        return memberList;
    }

    @Override
    public boolean save(Member entity) {

        String id = idGeneratorService.queryGeneratorId();

        if (StringUtils.isBlank(id)) {
            throw new ServiceException(CommonError.error("id生成失败,新增租户会员信息失败"));
        }
        entity.setId(Long.parseLong(id));
        entity.setCreatedTime(LocalDateTime.now());
        entity.setModifiedTime(LocalDateTime.now());
        int row = 0;
        try {
            row = baseMapper.insert(entity);
        } catch (ServiceException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (row <= 0) {
            throw new ServiceException(CommonError.error("新增租户会员信息失败"));
        }
        return true;
    }

    /**
     * @param page
     * @param queryWrapper
     * @param key
     * @return
     */
    @Override
    @Cacheable(cacheNames = "Member", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#key")
    @Logable(authName = "租户会员信息-根据租户会员信息进行分页查询")
    public IPage<Member> getPage(IPage<Member> page, QueryWrapper<Member> queryWrapper, String key) {
        return baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public TokenUsersVO getStoreMemberUserLoginDetail(Map<String, Object> map) {
        //  这个接口 临时用来  做登录  且  一个memberID 只能对应一个 店铺ID
        String phone =  map.getOrDefault("username","").toString();
        String memberId=(String)map.get("memberId");
        String storeId=(String) map.get("storeId");
        if (StringUtils.isBlank(phone) && memberId==null) {
            throw new ServiceException("手机号不能为空");
        }

        QueryWrapper<Member> tq = new QueryWrapper<>();
        tq.lambda().eq(StringUtils.isNotBlank(phone),Member::getPhone, phone)
                .eq(memberId!=null,Member::getId,memberId).eq(Member::getDeleted, 0);
        Member member = this.getOne(tq);
        if (null == member) {
            throw new ServiceException("用户不存在:"+phone);
        }

        QueryWrapper<StoreUsers> stuQ = new QueryWrapper<>();
        stuQ.lambda().eq(StoreUsers::getMemberId,member.getId()).eq(StoreUsers::getStoreId,storeId);
        StoreUsers storeUsers = storeUsersService.getOne(stuQ);
        if(storeUsers == null){
            log.error("用户信息异常#000000X1,store_user表无关联数据");
            throw new ServiceException("用户信息异常错误编码#000000X1，请联系管理员：" + phone);
        }

        PlatStore platStore = platStoreService.getById(storeUsers.getStoreId());
        if(null == platStore  ){
            log.error("用户信息异常#000000X3,店铺信息不存在");
            throw new ServiceException("用户信息异常#000000X3,请联系管理员:" + phone);
        }

        Platform platform = platformService.getById(platStore.getPlatId());
        if(null == platform  ){
            log.error("用户信息异常#000000X4,平台信息不存在");
            throw new ServiceException("用户信息异常错误编码#000000X4，请联系管理员：" + phone);
        }

        /*获取角色信息*/
        List<SysRoles> listRoles = sysRolesService.getRolesByUserId(member.getId());
        List<String> listRoleNames = listRoles.stream().map(role -> role.getName()).collect(Collectors.toList());
        List<SysPermissiones> listPem = sysPermissionesService.getSysPermissionesByUserId(member.getId());
        List<String> pemValueList = listPem.stream().filter(per -> StringUtils.isNotBlank(per.getUri()))
                .map(SysPermissiones::getPermissionValue).collect(Collectors.toList());
        List<String> urlList = listPem.stream().filter(per -> StringUtils.isNotBlank(per.getUri()))
                .map(SysPermissiones::getUri).collect(Collectors.toList());

        TokenUsersVO rs = new TokenUsersVO();
        BeanUtils.copyProperties(member, rs);
        rs.setUsername(member.getPhone());
        rs.setRealName(member.getRealName());
        rs.setUserId(storeUsers.getId());
        rs.setStoreId(storeUsers.getStoreId());
        rs.setPlatId(platStore.getPlatId());
        rs.setStoreName(platStore.getStoreName());
        rs.setStoreRole("管理员");
        rs.setCompanyId(platform.getCompanyId());
        rs.setRoleList(listRoleNames);
        rs.setPemValueList(pemValueList);
        rs.setUrlList(urlList);
        return rs;
    }

    @Override
    public TokenUsersVO getPlatformMemberUserLoginDetail(Map<String, Object> map) {
        //TODO 缓存处理
        String memberId=(String) map.get("memberId");
        String platformId=(String)map.get("platformId");
        if (memberId==null) {
            throw new ServiceException("会员ID不能为空");
        }

        QueryWrapper<Member> tq = new QueryWrapper<>();
        tq.lambda()
                .eq(memberId!=null,Member::getId,memberId).eq(Member::getDeleted, 0);
        Member member = this.getOne(tq);
        if (null == member) {
            throw new ServiceException("用户不存在");
        }

        QueryWrapper<PlatUsers> stuQ = new QueryWrapper<>();
        stuQ.lambda().eq(PlatUsers::getMemberId,memberId).eq(PlatUsers::getPlatformId,platformId);
        PlatUsers platUsers = platUsersService.getOne(stuQ);
        if(platUsers == null){
            log.error("用户信息异常#000000X1,plat_users表无关联数据");
            throw new ServiceException("用户信息异常错误编码#000000X1，请联系管理员");
        }
        Platform platform = platformService.getById(platUsers.getPlatformId());
        if(null == platform  ){
            log.error("用户信息异常#000000X4,平台信息不存在");
            throw new ServiceException("用户信息异常错误编码#000000X4，请联系管理员");
        }

        /*获取角色信息*/
        List<SysRoles> listRoles = sysRolesService.getRolesByUserId(platUsers.getId());
        List<String> listRoleNames = listRoles.stream().map(role -> role.getName()).collect(Collectors.toList());
        List<SysPermissiones> listPem = sysPermissionesService.getSysPermissionesByUserId(platUsers.getId());
        List<String> pemValueList = listPem.stream().filter(per -> StringUtils.isNotBlank(per.getUri()))
                .map(SysPermissiones::getPermissionValue).collect(Collectors.toList());
        List<String> urlList = listPem.stream().filter(per -> StringUtils.isNotBlank(per.getUri()))
                .map(SysPermissiones::getUri).collect(Collectors.toList());

        TokenUsersVO rs = new TokenUsersVO();
        BeanUtils.copyProperties(platUsers, rs);
        rs.setUsername(member.getPhone());
        rs.setUserId(platUsers.getId());
        rs.setPlatId(platUsers.getPlatformId());
        rs.setCompanyId(platform.getCompanyId());
        rs.setRoleList(listRoleNames);
        rs.setPemValueList(pemValueList);
        rs.setUrlList(urlList);
        return rs;
    }



}
